﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Lucene.Net.Analysis;
using Lucene.Net.Documents;
using Analyzer = Lucene.Net.Analysis.Analyzer;
using StandardAnalyzer = Lucene.Net.Analysis.Standard.StandardAnalyzer;
using Document = Lucene.Net.Documents.Document;
using Field = Lucene.Net.Documents.Field;
using IndexWriter = Lucene.Net.Index.IndexWriter;
using ParseException = Lucene.Net.QueryParsers.ParseException;
using QueryParser = Lucene.Net.QueryParsers.QueryParser;
using Directory = Lucene.Net.Store.Directory;
using RAMDirectory = Lucene.Net.Store.RAMDirectory;
using Version = Lucene.Net.Util.Version;
using IndexSearcher = Lucene.Net.Search.IndexSearcher;
using Query = Lucene.Net.Search.Query;
using ScoreDoc = Lucene.Net.Search.ScoreDoc;
using Store = Lucene.Net.Store;
using Could.Service;
using IO = System.IO;
using System.Diagnostics;
using Lucene.Net.Index;
using MySql.Data.MySqlClient;
using System.Collections;

namespace CatSentenceAnalyzer
{
    public class TDBIndexClass : CatIndexClass
    {
        Hashtable m_TdbHashT ;
        public TdbMysql m_TdbEngineSql;
        public TDBIndexClass(){
            m_EngineSql = m_TdbEngineSql = new TdbMysql();
        }
        public override void CommandExe()
        {
            //m_Indexpath = m_npc.PrivateIndexTDBPath;
            //m_EnginxID = m_npc.EnginxID;
            m_EngineSql.m_npc = m_npc;
            base.CommandExe();
        }
        public override void CreateIndex()
        {
            using (MySqlDataReader reader = m_EngineSql.SelectFrom())
            {
                Directory directory = IndexDirectory;
                Analyzer analyzer = GetCatAnalyzer(CLangSegment.TDBALLINDEXTYPE);
                IndexWriter writer = GetCatWriter(directory, analyzer);
                Single boost = 0f;
                try
                {
                    while (reader.Read())
                    {
                        Document doc = new Document();
                        boost = Convert.ToInt32(reader.GetValue(reader.GetOrdinal(SqlDB.WLENFIELD)).ToString());
                        doc.Add(new Field(SqlDB.IDFIELD, reader.GetValue(reader.GetOrdinal(SqlDB.IDFIELD)).ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
                        doc.Add(new Field(SqlDB.SUMFIELD, reader.GetValue(reader.GetOrdinal(SqlDB.SUMFIELD)).ToString(), Field.Store.YES, Field.Index.NO));
                        doc.Add(new Field(SqlDB.WLENFIELD, boost.ToString(), Field.Store.YES, Field.Index.NO));
                        doc.Add(new Field(SqlDB.TEXTFIELD, reader.GetValue(reader.GetOrdinal(m_npc.transdata.textTdbField)).ToString(), Field.Store.YES, Field.Index.NO));
                        doc.Add(new Field(SqlDB.INDEXFIELD, reader.GetValue(reader.GetOrdinal(m_npc.transdata.indexTdbField)).ToString(), Field.Store.YES, Field.Index.ANALYZED));
                        doc.SetBoost(boost);
                        writer.AddDocument(doc);
                    }
                }
                catch (System.Exception) { }
                finally
                {
                    writer.Optimize();
                    writer.Close();
                    directory.Close();
                }
            }
        }

        public override void DeleteIndex()
        {
            if (m_EngineSql.DeleteFromID())
            {
                int i;
                Store.Directory directory = IndexDirectory;
                IndexReader reader = IndexReader.Open(directory, false);
                Term term = new Term(SqlDB.IDFIELD, m_npc.transdata.TdbID.ToString());
                i = reader.DeleteDocuments(term);
                reader.Close();
                directory.Close();
            }
        }

        public override void UpdateIndex()
        {
            Tdb tdb = GetUpdateTDB();
            if (tdb !=null && m_npc.transdata.TLibrary != tdb.tTerm)//译文不同， 修改
            {
                m_npc.transdata.TdbID = Convert.ToInt32(tdb.ID);
                if (m_EngineSql.UpdateFromID())
                {
                    Store.Directory directory = IndexDirectory;
                    Analyzer analyzer = GetCatAnalyzer(CLangSegment.TDBALLINDEXTYPE);
                    IndexWriter iwriter = GetCatWriter(directory, analyzer);
                    Document doc = new Document();
                    doc.Add(new Field(SqlDB.IDFIELD, tdb.ID, Field.Store.YES, Field.Index.NOT_ANALYZED));
                    doc.Add(new Field(SqlDB.SUMFIELD, tdb.SumKey.ToString(), Field.Store.YES, Field.Index.NO));
                    doc.Add(new Field(SqlDB.WLENFIELD, tdb.WordLen.ToString(), Field.Store.YES, Field.Index.NO));
                    doc.Add(new Field(SqlDB.TEXTFIELD, m_npc.transdata.TLibrary, Field.Store.YES, Field.Index.NO));
                    doc.Add(new Field(SqlDB.INDEXFIELD, m_npc.transdata.OLibrary, Field.Store.YES, Field.Index.ANALYZED));
                    iwriter.UpdateDocument(new Term(SqlDB.IDFIELD, tdb.ID), doc);
                    iwriter.Close();
                    directory.Close();
                }
                else
                { 
                    //((TmsMysql)(m_EngineSql)).UpdateFrom_UsageCount(tms.ID);
                }
            }
        }

        public override void SearchIndex()
        {
            string key = GetTokens(m_npc.transdata.OLibrary, CLangSegment.MININDEXTYPE);
            if (SearchIndex(key))
            {
                UpdateIndex();
            }
            else
            {
                AddNewIndex();
            }
        }
        public override void FuzzyIndex(int level)
        { FuzzyIndex(); }
        public override void FuzzyIndex()
        {
            string key = ""; int sum = 0;
            Hashtable ht = new Hashtable();
            ArrayList list = GetListColl();
            m_arrResult = new ArrayList();
            for (int i = 0; i < list.Count; i++)
            {
                key = list[i].ToString();
                if (!ht.ContainsKey(key))
                {
                    ht.Add(key, key);
                    if (SearchIndex(key))
                    {
                        //m_arrResult = new ArrayList();
                        foreach (int k in m_TdbHashT.Keys)
                        {
                            ArrayList arrlist = new ArrayList();
                            Hashtable sublist = m_TdbHashT[k] as Hashtable;
                            sum = 0;
                            if ((i + k - 1) < list.Count)
                            {
                                for (int z = 0; z < k; z++)
                                {
                                    sum += Convert.ToInt32(list[i + z]);
                                }
                                arrlist = sublist[sum] as ArrayList;
                            }

                            if (arrlist != null)
                                foreach (Tdb tdb in arrlist)
                                {
                                    m_arrResult.Add(tdb);
                                }
                        }
                    }
                }
            }
            m_npc.transdata.ArrList = m_arrResult;
        }

        public override void MaketransData()
        {
            TransData td = m_npc.transdata;
            td.TdbTitle = "术语，获得|1|条结果,用时(|2|秒),匹配相关10个厂家";
            td.TdbTitle = td.TdbTitle.Replace("|1|", td.ArrList.Count.ToString());
            td.TdbTitle = td.TdbTitle.Replace("|2|", ((Convert.ToSingle(m_npc.transdata.ElapsedTime)) / 1000).ToString());
            ////td.TdbResult = "<img src='http://localhost/catweb/assets/images/5.png'>" + "this's ：这是\n" + "解释：这是什么？\n" + "相关厂家:<a href='event:www.baidu.com' target='_blank'>百度<\a>";
            //string tmp ="" ;
            //string sample = "<li><font size='10' color='#000000'>|1|</font>\n<font size='10' color='#3399ff'>|2|</font></li>\n";
            //for (int i = 0; i < m_arrResult.Count; i++)
            //{
            //    Tdb tdb = m_arrResult[i] as Tdb;
            //    tmp += sample.Replace("|1|", tdb.oTerm);
            //    tmp = tmp.Replace("|2|", tdb.tTerm);
            //}
            //td.TdbResult = tmp;

        }
        public override bool AddNewIndex()
        {
            GetTDBParamter(ref m_TdbEngineSql.wordlen ,ref m_TdbEngineSql.sumkey);
            int newid = m_TdbEngineSql.InsertInto();
            if (newid > 0)
            {
                Store.Directory directory = IndexDirectory;
                Analyzer analyzer = GetCatAnalyzer(CLangSegment.TDBALLINDEXTYPE);
                IndexWriter writer = GetCatAppendWriter(directory, analyzer);
                Document doc = new Document();
                doc.Add(new Field(SqlDB.IDFIELD, newid.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
                doc.Add(new Field(SqlDB.SUMFIELD, m_TdbEngineSql.sumkey.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
                doc.Add(new Field(SqlDB.WLENFIELD, m_TdbEngineSql.wordlen.ToString(), Field.Store.YES, Field.Index.NO));
                doc.Add(new Field(SqlDB.TEXTFIELD, m_npc.transdata.TLibrary, Field.Store.YES, Field.Index.NO));
                doc.Add(new Field(SqlDB.INDEXFIELD, m_npc.transdata.OLibrary, Field.Store.YES, Field.Index.ANALYZED));
                doc.SetBoost( m_TdbEngineSql.wordlen );
                writer.AddDocument(doc);
                writer.Close();
                directory.Close();
            }
            return newid > 0;
        }

        public override bool SearchIndex(string key)
        {
            Store.Directory directory = IndexDirectory;
            IndexSearcher isearcher = new IndexSearcher(directory, true); // read-only=true
            WhitespaceAnalyzer analyzer = new WhitespaceAnalyzer();
            QueryParser parser = new QueryParser(Version.LUCENE_29, SqlDB.INDEXFIELD, analyzer);
            Query query = parser.Parse(key);
            ScoreDoc[] hits = isearcher.Search(query, null, 100).scoreDocs;

            m_TdbHashT = new Hashtable();
            Hashtable sublist; ArrayList subarr = null;

            for (int i = 0; i < hits.Length; i++)
            {
                Document hitDoc = isearcher.Doc(hits[i].doc);
                Tdb tdb = new Tdb();
                tdb.ID = hitDoc.Get(SqlDB.IDFIELD);
                tdb.oTerm = hitDoc.Get(SqlDB.INDEXFIELD);
                tdb.tTerm = hitDoc.Get(SqlDB.TEXTFIELD);
                tdb.WordLen = Convert.ToInt32(hitDoc.Get(SqlDB.WLENFIELD));
                tdb.SumKey = Convert.ToInt32(hitDoc.Get(SqlDB.SUMFIELD));
                //m_arrResult.Add(tdb);

                if (m_TdbHashT.ContainsKey(tdb.WordLen))
                {
                    sublist = m_TdbHashT[tdb.WordLen] as Hashtable;
                    if (!sublist.ContainsKey(tdb.SumKey))
                    {
                        subarr = new ArrayList();
                        subarr.Add(tdb);
                        sublist.Add(tdb.SumKey, subarr);
                    }
                    else
                    {
                        subarr = sublist[tdb.SumKey] as ArrayList;
                        subarr.Add(tdb);
                    }
                }
                else
                {
                    sublist = new Hashtable();
                    subarr = new ArrayList();
                    subarr.Add(tdb);
                    sublist.Add(tdb.SumKey, subarr);
                    m_TdbHashT.Add(tdb.WordLen, sublist);
                }
            }
            isearcher.Close();
            directory.Close();
            return hits.Length > 0;
        }


        private void GetTDBParamter(ref int wordlen, ref int sumkey)
        {
            CATSegTokenizer cst = GetTokensList(CLangSegment.SUMKEYINDEXTYPE);            
            cst.GetSegment();

            sumkey = CLangSegment.SumKey(cst.m_MatchList[0].ToString());
            wordlen = cst.GetSumKeyWordLength();
        }

        private ArrayList GetListColl()
        {
            CATSegTokenizer cst = GetTokensList(CLangSegment.TDBCOLLTYPE);            
            cst.GetSegment();
            return cst.m_MatchSumKey;
        }

        private Tdb GetUpdateTDB()
        {
            Tdb tdb = null;
            if (m_TdbHashT.Count > 0)
            {
                ArrayList keys = new ArrayList(m_TdbHashT.Keys);
                Hashtable ht = m_TdbHashT[keys[0]] as Hashtable;
                keys = new ArrayList(ht.Keys);
                m_arrResult = ht[keys[0]] as ArrayList;

                tdb = m_arrResult[0] as Tdb;
            }
            return tdb;
        }

        public override void ReadDocs(int min, int max)
        {
            throw new NotImplementedException();
        }
    }

    public class PrivateTDBIndexClass : TDBIndexClass
    {
        public PrivateTDBIndexClass()
        {
            MainIndex = false;
            m_EngineSql = new PrivateTdbMysql();
        }
        public override void CommandExe()
        {
            m_Indexpath = m_npc.PrivateIndexTDBPath;
            base.CommandExe();
        }
    }
    public class MainTDBIndexClass : TDBIndexClass
    {
        public MainTDBIndexClass()
        {
            MainIndex = true;
            m_EngineSql = m_TdbEngineSql = new MainTdbMysql();
        }
        public override void CommandExe()
        {
            m_Indexpath = m_npc.MainIndexTDBPath;
            base.CommandExe();
        }
    }
}
